package com.gitee.sop.layui.adminserver.module.background.system.api.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gitee.easyopen.doc.annotation.ApiDoc;
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
import com.gitee.easyopen.util.CopyUtil;
import com.gitee.sop.layui.adminserver.module.background.system.api.service.param.ConfigIpBlackForm;
import com.gitee.sop.layui.adminserver.module.background.system.api.service.param.ConfigIpBlacklistPageParam;
import com.gitee.sop.layui.adminserver.module.background.system.api.service.result.ConfigIpBlacklistVO;
import com.gitee.sop.layui.adminserver.module.background.system.bean.ChannelMsg;
import com.gitee.sop.layui.adminserver.module.background.system.bean.NacosConfigs;
import com.gitee.sop.layui.adminserver.module.background.system.common.ChannelOperation;
import com.gitee.sop.layui.adminserver.module.background.system.entity.ConfigIpBlacklist;
import com.gitee.sop.layui.adminserver.module.background.system.mapper.ConfigIpBlacklistMapper;
import com.gitee.sop.layui.adminserver.module.background.system.service.ConfigPushService;
import com.gitee.sop.layui.adminserver.module.base.constants.Result;
import com.gitee.sop.layui.adminserver.module.base.error.ServiceInterruptionException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author admin
 */
@RestController
@ApiDoc("IP黑名单管理")
@Slf4j
public class IPBlacklistApi {

    @Autowired
    ConfigIpBlacklistMapper configIpBlacklistMapper;

    @Autowired
    private ConfigPushService configPushService;

    @GetMapping("/api/ip.blacklist.page")
    @ApiDocMethod(description = "获取IP黑名单，分页")
    Result page(ConfigIpBlacklistPageParam form) {
        Page<ConfigIpBlacklist> page = new Page<>(form.getPageIndex(), form.getPageSize());
        LambdaQueryWrapper<ConfigIpBlacklist> wrapper = new QueryWrapper<ConfigIpBlacklist>().lambda().orderByDesc(ConfigIpBlacklist::getId);
        wrapper.like(StringUtils.isNotBlank(form.getIp()), ConfigIpBlacklist::getIp, form.getIp());
        configIpBlacklistMapper.selectPage(page, wrapper);
        List<ConfigIpBlacklist> records = page.getRecords();
        List<ConfigIpBlacklistVO> retList = records.stream()
                .map(role -> {
                    ConfigIpBlacklistVO vo = new ConfigIpBlacklistVO();
                    CopyUtil.copyProperties(role, vo);
                    return vo;
                })
                .collect(Collectors.toList());
        return Result.successPage(retList, page.getTotal(), page.getCurrent(), page.getSize());
    }

    @PostMapping("/api/ip.blacklist.add")
    @ApiDocMethod(description = "IP黑名单--新增")
    Result add(ConfigIpBlackForm form) {
        ConfigIpBlacklist rec = configIpBlacklistMapper.selectOne(new QueryWrapper<ConfigIpBlacklist>().lambda().eq(ConfigIpBlacklist::getIp, form.getIp()));
        if (rec != null) {
            throw ServiceInterruptionException.fail(500, "IP已添加");
        }
        rec = new ConfigIpBlacklist();
        CopyUtil.copyPropertiesIgnoreNull(form, rec);
        configIpBlacklistMapper.insert(rec);
        try {
            this.sendIpBlacklistMsg(rec, ChannelOperation.BLACKLIST_ADD);
        } catch (Exception e) {
            log.error("推送IP黑名单失败, rec:{}", rec, e);
            throw ServiceInterruptionException.fail(500, "推送IP黑名单失败");
        }
        return Result.success();
    }

    @PostMapping("/api/ip.blacklist.update")
    @ApiDocMethod(description = "IP黑名单--修改")
    Result update(ConfigIpBlackForm form) {
        ConfigIpBlacklist rec = configIpBlacklistMapper.selectById(form.getId());
        CopyUtil.copyPropertiesIgnoreNull(form, rec);
        configIpBlacklistMapper.updateById(rec);
        return Result.success();
    }

    @PostMapping("/api/ip.blacklist.del")
    @ApiDocMethod(description = "IP黑名单--删除")
    Result del(long id) {
        ConfigIpBlacklist rec = configIpBlacklistMapper.selectById(id);
        if (rec == null) {
            return Result.fail("操作失败");
        }
        configIpBlacklistMapper.deleteById(id);
        try {
            this.sendIpBlacklistMsg(rec, ChannelOperation.BLACKLIST_DELETE);
        } catch (Exception e) {
            log.error("推送IP黑名单失败, rec:{}", rec, e);
            throw ServiceInterruptionException.fail(500, "推送IP黑名单失败");
        }
        return Result.success();
    }

    @GetMapping("/api/ip.blacklist.get")
    @ApiDocMethod(description = "IP黑名单--详情")
    Result get(long id) {
        ConfigIpBlacklist rec = configIpBlacklistMapper.selectById(id);
        return Result.success(rec);
    }


    public void sendIpBlacklistMsg(ConfigIpBlacklist configIpBlacklist, ChannelOperation channelOperation) {
        ChannelMsg channelMsg = new ChannelMsg(channelOperation, configIpBlacklist);
        configPushService.publishConfig(NacosConfigs.DATA_ID_IP_BLACKLIST, NacosConfigs.GROUP_CHANNEL, channelMsg);
    }

}
